#include "app_uv_control.h"
#include "app_uv_pwm.h"
#include "app_eeprom_manage.h"
#include "flow.h"
#include "usart4.h"  // for UART5_Printf
#include "CJHR31.h"  // for humidityData


/* ===================== 静态函数声明 ===================== */

static void uv_state_humidity_check(void);
static void uv_state_worktime_check(void);
static void uv_state_ignore2_check(void);
static void uv_state_flow_check(void);
static void uv_state_radiation_check(void);
static void uv_state_locked_worktime(void);
static void uv_state_locked_radiation(void);


/* ===================== 函数实现 ===================== */

/**
 * @brief  UV灯控制初始化
 * @param  None
 * @retval None
 */
void app_uv_control_init(void)
{
    // 初始化UV灯为关闭状态
    app_uv_stop();
    g_user_config.uv_current_mode = 0;

    // 状态机初始化为湿度检测状态
    g_user_config.uv_state = UV_STATE_HUMIDITY_CHECK;

    UART5_Printf("[UV Control] Initialized - State machine started\r\n");
    UART5_Printf("[UV] Initial values: humidity=%.1f%%, radiation=%d, flow=%.1f\r\n",
                 g_user_config.humidity, g_user_config.uv_radiation, g_user_config.flow_instant);
}


/**
 * @brief  UV灯工作时间累计tick (每1秒调用一次)
 * @param  None
 * @retval None
 * @note   在TIM7中断中调用,只有100%电流工作时才累计
 */
void app_uv_worktime_tick(void)
{
    static uint32_t uv_work_seconds = 0;

    // 只有100%电流工作时才累计
    if (g_user_config.uv_current_mode == 2)
    {
        uv_work_seconds++;

        // 每小时保存一次到EEPROM
        if (uv_work_seconds >= 3600)
        {
            g_user_config.uv_total_work_hours++;
            app_eeprom_save_uv_worktime(g_user_config.uv_total_work_hours);
            uv_work_seconds = 0;

            UART5_Printf("[UV] Worktime: %lu hours saved to EEPROM\r\n",
                         g_user_config.uv_total_work_hours);
        }
    }
}


/**
 * @brief  UV灯主控制逻辑 - 6步状态机
 * @param  None
 * @retval None
 * @note   在主循环中周期性调用(建议100ms)
 */
void app_uv_control_process(void)
{
    switch (g_user_config.uv_state)
    {
        case UV_STATE_INIT:
            // 初始化状态,跳转到湿度检测(跳过电路检测)
            g_user_config.uv_state = UV_STATE_HUMIDITY_CHECK;
            UART5_Printf("[UV] State: INIT -> HUMIDITY_CHECK\r\n");
            break;

        case UV_STATE_HUMIDITY_CHECK:
            // 步骤1: 湿度检测
            uv_state_humidity_check();
            break;

        case UV_STATE_WORKTIME_CHECK:
            // 步骤2: UV工作时间检测
            uv_state_worktime_check();
            break;

        case UV_STATE_IGNORE2_CHECK:
            // 步骤3: 检测"忽略2"标志位
            uv_state_ignore2_check();
            break;

        case UV_STATE_FLOW_CHECK:
            // 步骤4: 流量检测
            uv_state_flow_check();
            break;

        case UV_STATE_RADIATION_CHECK:
            // 步骤5: UV辐射度检测
            uv_state_radiation_check();
            break;

        case UV_STATE_RUNNING:
            // 正常运行状态,循环回到湿度检测
            g_user_config.uv_state = UV_STATE_HUMIDITY_CHECK;
            break;

        case UV_STATE_LOCKED_WORKTIME:
            // 锁定状态-工作时间超时
            uv_state_locked_worktime();
            break;

        case UV_STATE_LOCKED_RADIATION:
            // 锁定状态-辐射度不足
            uv_state_locked_radiation();
            break;

        default:
            // 异常状态,重置到初始化
            g_user_config.uv_state = UV_STATE_INIT;
            UART5_Printf("[UV] ERROR: Invalid state, reset to INIT\r\n");
            break;
    }
}


/* ===================== 静态辅助函数实现 ===================== */

/**
 * @brief  步骤1: 湿度检测(按流程图文档)
 * @note   湿度 < 阈值 → 器件正常,继续
 *         湿度 ≥ 阈值 → 器件爆管(漏水),关闭电磁阀,结束
 */
static void uv_state_humidity_check(void)
{
    // 更新湿度数据
    app_valve_update_humidity();

    // 读取当前湿度
    float current_humidity = g_user_config.humidity;

    UART5_Printf("[UV] Humidity check: %.1f%% (threshold=%d%%, uv_mode=%d, valve=%d)\r\n",
                 current_humidity, g_user_config.humidity_threshold,
                 g_user_config.uv_current_mode, g_user_config.valve_is_open);

    if (current_humidity < g_user_config.humidity_threshold)
    {
        // 湿度小于阈值,器件正常,进入UV工作时间检测
        g_user_config.uv_state = UV_STATE_WORKTIME_CHECK;
    }
    else
    {
        // 湿度大于等于阈值,器件爆管(漏水),关闭电磁阀和UV灯,停止流程
        Valve_Close;  // 关闭电磁阀
        g_user_config.valve_is_open = 0;

        app_uv_stop();  // 停止UV灯
        g_user_config.uv_current_mode = 0;

        // 保持在湿度检测状态,等待湿度恢复
        UART5_Printf("[UV] Humidity too high: %.1f%% >= %d%%, valve closed (leak detected)\r\n",
                     current_humidity, g_user_config.humidity_threshold);
    }
}


/**
 * @brief  步骤2: UV工作时间检测(按流程图文档)
 * @note   先检测"忽略1"标志位 → 有则跳过
 *         无则检测工作时间 > 15000H → 锁定,关闭电磁阀
 */
static void uv_state_worktime_check(void)
{
    // 检查"忽略1"标志位
    if (g_user_config.uv_ignore_flag1 == 1)
    {
        // 已设置"忽略1",跳过工作时间检测,进入"忽略2"检测
        g_user_config.uv_state = UV_STATE_IGNORE2_CHECK;
        return;
    }

    // 检查UV累计工作时间
    if (g_user_config.uv_total_work_hours >= 15000)
    {
        // 工作时间超过15000小时,进入锁定状态
        g_user_config.uv_state = UV_STATE_LOCKED_WORKTIME;

        // 关闭电磁阀和UV灯(按流程图L34)
        Valve_Close;
        g_user_config.valve_is_open = 0;

        app_uv_stop();
        g_user_config.uv_current_mode = 0;

        UART5_Printf("[UV] LOCKED: Worktime %lu hours >= 15000H, valve closed\r\n",
                     g_user_config.uv_total_work_hours);
    }
    else
    {
        // 工作时间未超时,继续进入"忽略2"检测
        g_user_config.uv_state = UV_STATE_IGNORE2_CHECK;
    }
}


/**
 * @brief  步骤3: 检测"忽略2"标志位
 * @note   有 → UV灯100%,开阀,结束
 *         无 → 进入流量检测
 */
static void uv_state_ignore2_check(void)
{
    if (g_user_config.uv_ignore_flag2 == 1)
    {
        // 已设置"忽略2",直接开启UV灯100%,开启电磁阀
        app_uv_set_current(100);
        g_user_config.uv_current_mode = 2;

        Valve_Open;
        g_user_config.valve_is_open = 1;

        // 进入运行状态
        g_user_config.uv_state = UV_STATE_RUNNING;

        UART5_Printf("[UV] Ignore2 active: UV 100%%, valve open\r\n");
    }
    else
    {
        // 未设置"忽略2",进入流量检测
        g_user_config.uv_state = UV_STATE_FLOW_CHECK;
    }
}


/**
 * @brief  步骤4: 流量检测(按流程图文档L58-66)
 * @note   流量 > 阈值 → UV灯100%,进入辐射度检测
 *         流量 ≤ 阈值 → UV灯10%,开启电磁阀,结束
 */
static void uv_state_flow_check(void)
{
    // 读取当前瞬时流量
    float current_flow = golbal_flow.instant;

    if (current_flow > g_user_config.flow_threshold)
    {
        // 有水流,UV灯100%,保存工作时间,进入辐射度检测
        app_uv_set_current(100);
        g_user_config.uv_current_mode = 2;

        g_user_config.uv_state = UV_STATE_RADIATION_CHECK;

        UART5_Printf("[UV] Flow detected: %.1f L/H > %d, UV 100%%\r\n",
                     current_flow, g_user_config.flow_threshold);
    }
    else
    {
        // 无水流,UV灯10%,不保存工作时间,开启电磁阀,结束
        app_uv_set_current(10);
        g_user_config.uv_current_mode = 1;

        Valve_Open;
        g_user_config.valve_is_open = 1;

        // 进入运行状态
        g_user_config.uv_state = UV_STATE_RUNNING;

        UART5_Printf("[UV] No flow: %.1f L/H <= %d, UV 10%%, valve open\r\n",
                     current_flow, g_user_config.flow_threshold);
    }
}


/**
 * @brief  步骤5: UV辐射度检测(按流程图文档L70-74)
 * @note   辐射度 ≥ Value_100 → 确定开启电磁阀,结束
 *         辐射度 < Value_100 → 锁定,关闭电磁阀
 */
static void uv_state_radiation_check(void)
{
    // 读取当前UV辐射度
    uint16_t current_radiation = g_user_config.uv_radiation;

    if (current_radiation >= g_user_config.uv_value_100)
    {
        // 辐射度合格,确定开启电磁阀,进入运行状态
        Valve_Open;
        g_user_config.valve_is_open = 1;

        g_user_config.uv_state = UV_STATE_RUNNING;

        UART5_Printf("[UV] Radiation OK: %d >= %d, valve open\r\n",
                     current_radiation, g_user_config.uv_value_100);
    }
    else
    {
        // 辐射度不足,进入锁定状态,关闭电磁阀(按流程图L74)
        g_user_config.uv_state = UV_STATE_LOCKED_RADIATION;

        Valve_Close;
        g_user_config.valve_is_open = 0;

        app_uv_stop();
        g_user_config.uv_current_mode = 0;

        UART5_Printf("[UV] LOCKED: Radiation %d < %d, valve closed\r\n",
                     current_radiation, g_user_config.uv_value_100);
    }
}


/**
 * @brief  锁定状态-工作时间超时(按流程图文档)
 * @note   等待按键: "忽略1" or "更换成功"
 *         "忽略1"按下 → 设置忽略标志,解除锁定,进入"忽略2"检测
 *         "更换成功"按下 → 清除所有数据,重新初始化
 */
static void uv_state_locked_worktime(void)
{
    // 状态机在此等待,按键处理在app_main.c中的handle_button_events()中完成
    // 按键处理函数会修改uv_state跳出锁定

    // 保持电磁阀关闭和UV灯关闭
    Valve_Close;
    g_user_config.valve_is_open = 0;

    app_uv_stop();
    g_user_config.uv_current_mode = 0;

    // 可以在这里添加屏幕显示提示
    // 例如: tjc_send_txt("msg", "txt", "UV工作时间超时,请更换UV灯或按忽略1");
}


/**
 * @brief  锁定状态-辐射度不足(按流程图文档)
 * @note   等待按键: "忽略2" or "更换成功"
 *         "忽略2"按下 → 设置忽略标志,解除锁定,进入运行状态
 *         "更换成功"按下 → 清除所有数据,重新初始化
 */
static void uv_state_locked_radiation(void)
{
    // 状态机在此等待,按键处理在app_main.c中的handle_button_events()中完成
    // 按键处理函数会修改uv_state跳出锁定

    // 保持电磁阀关闭和UV灯关闭
    Valve_Close;
    g_user_config.valve_is_open = 0;

    app_uv_stop();
    g_user_config.uv_current_mode = 0;

    // 可以在这里添加屏幕显示提示
    // 例如: tjc_send_txt("msg", "txt", "UV辐射度不足,请更换UV灯或按忽略2");
}
